<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
  </style>
</head>

<body>
  <ul>
    <li>title 1</li>
    <li>title 2</li>
  </ul>
  <button>交换</button>
  <!-- 元素交换怎么应用过渡呢,过度是 A -> B,可以应用过度,元素交换没办法啊 -->
  <!-- 宽度和高度从一个值到auto,也没办法用过度 -->
  <!-- 
        这种没办法的情况可以用Flip, 比方说: A -> B, 他不是直接从A 过度到 B
        1. 记录变化之前的位置
        2. 没有过度的从A变化到B
        3. 记录变化之后的位置
        4. 计算位置的差值
        5. 将元素回退到之前的位置
        6. 去掉移动回去的样式,加上过渡即可, 比如通过translate移动回去了,这时候加上过渡,在去掉样式,他就又移动回来了

        flip是一个翻转的思维
        flip就是一种思路,不是什么第三方库
        下面是一个示例,就是这个思路,真正的flip是怎么实现的不知道
       -->

  <script>
    var btn = document.querySelector("button");

    // 当浏览器下一次渲染之后，调用回调
    function raf(callback) { // vue就是这样做的
      requestAnimationFrame(() => { // 这个函数是在下一次渲染之前调用回调
        requestAnimationFrame(callback); // 在注册一次
      });
    }

    function getY(dom) {
      return dom.getBoundingClientRect().top;
      // 还有一个类似的方法getClientRects,可以查查文档
    }

    function applyTransition(dom, initY) {
      var curY = getY(dom); //记录变化后的位置
      var dis = initY - curY; //计算位置的差值
      dom.style.transform = `translateY(${dis}px)`;
      // 1. 强行渲染,之后把transform设成none


      // 2. 监听渲染帧
      // 渲染之后
      raf(() => {
        // vue的v-move只需要加入transition就可以了,其他的步骤都帮我们做好了
        dom.style.transition = ".5s"; // vue的v-move就是在这个时机加入的transition
        dom.style.transform = "none";
        dom.addEventListener(
          "transitionend",
          () => {
            dom.style.transition = "none"; // 移除不然影响下一次
          },
          {
            once: true, // 只执行一次,就销毁事件,下一次又会加上这个事件
          }
        );
      });
    }

    btn.onclick = function () {
      var ul = document.querySelector("ul");
      var li1 = document.querySelector("ul li:nth-child(1)");
      var li1Y = getY(li1); // 拿到li1的初始位置
      var li2 = document.querySelector("ul li:nth-child(2)");
      var li2Y = getY(li2); // 拿到li2的初始位置
      ul.insertBefore(li2, li1); // 没有任何过渡效果的变化

      applyTransition(li1, li1Y);
      applyTransition(li2, li2Y);
    };
  </script>
</body>

</html>